package com.eastfair.home.service.impl;

import cn.hutool.core.bean.BeanUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.home.dao.ReportDrawingCategoryAuditMapper;
import com.eastfair.home.dto.ReportDrawingAuditDTO;
import com.eastfair.home.dto.ReportDrawingCategoryAuditDTO;
import com.eastfair.home.entity.Drawing;
import com.eastfair.home.entity.ReportDrawingAudit;
import com.eastfair.home.entity.ReportDrawingCategoryAudit;
import com.eastfair.home.entity.ReportSpaceAudit;
import com.eastfair.home.enumeration.ReportDrawingCategoryAuditAuditStatusEnum;
import com.eastfair.home.enumeration.ReportDrawingCategoryAuditDrawingAuditStatusEnum;
import com.eastfair.home.enumeration.ReportDrawingCategoryAuditVenueAuditStatusEnum;
import com.eastfair.home.enumeration.ReportSpaceAuditDrawingAuditStatusEnum;
import com.eastfair.home.exceptioncode.HomeExceptionCode;
import com.eastfair.home.service.*;
import com.eastfair.home.vo.ReportDrawingCategoryAuditVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 报馆图纸分类审核记录
 * </p>
 *
 * @author dq
 * @date 2022-08-08
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ReportDrawingCategoryAuditServiceImpl extends SuperServiceImpl<ReportDrawingCategoryAuditMapper, ReportDrawingCategoryAudit> implements ReportDrawingCategoryAuditService {

    @Resource
    private ReportDrawingAuditService reportDrawingAuditService;

    @Resource
    private ReportDrawingCategoryAuditHistoryService reportDrawingCategoryAuditHistoryService;

    @Resource
    private ReportSpaceAuditService reportSpaceAuditService;

    @Resource
    private DrawingService drawingService;

    @Resource
    private HomeHomeBuilderDrawingCategoryAuditService homeHomeBuilderDrawingCategoryAuditService;

    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ReportDrawingCategoryAudit> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ReportDrawingCategoryAudit model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());

        model.setReportTime(LocalDateTime.now());
        model.setAuditStatus(ReportDrawingCategoryAuditAuditStatusEnum.SUBMIT);
        model.setAuditOpinion(null);
        model.setAuditTime(null);
        model.setAuditUserId(null);
        model.setAuditUserName(null);
        if (model.getIsPoint() == null || model.getIsPoint() == BusinessConstant.NO) {
            model.setVenueAuditStatus(ReportDrawingCategoryAuditVenueAuditStatusEnum.NOT_NEED_AUDIT);
        } else {
            model.setVenueAuditStatus(ReportDrawingCategoryAuditVenueAuditStatusEnum.SUBMIT);
            model.setVenueAuditOpinion(null);
            model.setVenueAuditTime(null);
            model.setVenueAuditUserId(null);
            model.setVenueAuditUserName(null);
        }
        model.setDrawingAuditStatus(ReportDrawingCategoryAuditDrawingAuditStatusEnum.SUBMIT);
        return R.successDef();
    }

    @Override
    public List<ReportDrawingCategoryAuditVO> listVOByReportSpaceAuditId(Long reportSpaceAuditId) {
        log.info("listVOByReportSpaceAuditId - 报馆审核ID查询图纸分类审核列表, reportSpaceAuditId={}", reportSpaceAuditId);
        List<ReportDrawingCategoryAudit> list = listByReportSpaceAuditId(reportSpaceAuditId);
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        return list.stream()
                .map(reportDrawingCategory -> BeanUtil.toBean(reportDrawingCategory, ReportDrawingCategoryAuditVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public List<ReportDrawingCategoryAudit> listByReportSpaceAuditId(Long reportSpaceAuditId) {
        log.info("listByReportSpaceAuditId - 报馆审核ID查询图纸分类审核列, reportSpaceAuditId={}", reportSpaceAuditId);
        ReportDrawingCategoryAuditDTO query = new ReportDrawingCategoryAuditDTO();
        query.setReportSpaceAuditId(reportSpaceAuditId);
        return listReportDrawingCategoriesAudits(query);
    }

    @Override
    public List<ReportDrawingCategoryAuditVO> listVOByReportSpaceId(Long reportSpaceId) {
        log.info("listVOByReportSpaceId - 报馆ID查询图纸分类审核VO列表, reportSpaceId={}", reportSpaceId);
        List<ReportDrawingCategoryAudit> list = listByReportSpaceId(reportSpaceId);
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        // 查询主场设置的图纸分类
        List<Long> drawingCategoryIdList = list
                .stream()
                .map(ReportDrawingCategoryAudit::getDrawingCategoryId)
                .collect(Collectors.toList());
        List<Drawing> drawingList = drawingService.listByIds(drawingCategoryIdList);
        Map<Long, Drawing> drawingMap = new HashMap<>(16);
        drawingList.forEach(drawing -> drawingMap.put(drawing.getId(), drawing));
        // 转换数据
        return list
                .stream()
                .map(reportDrawingCategoryAudit -> {
                    ReportDrawingCategoryAuditVO reportDrawingCategoryAuditVO = BeanUtil.toBean(reportDrawingCategoryAudit, ReportDrawingCategoryAuditVO.class);
                    // 封装图纸示例与规范说明
                    Drawing drawing = drawingMap.get(reportDrawingCategoryAuditVO.getDrawingCategoryId());
                    if (drawing != null) {
                        reportDrawingCategoryAuditVO.setSpecification(drawing.getSpecification());
                        reportDrawingCategoryAuditVO.setImageUrl(drawing.getImageUrl());
                    }
                    return reportDrawingCategoryAuditVO;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<ReportDrawingCategoryAudit> listByReportSpaceId(Long reportSpaceId) {
        ReportDrawingCategoryAuditDTO query = new ReportDrawingCategoryAuditDTO();
        query.setReportSpaceId(reportSpaceId);
        return listReportDrawingCategoriesAudits(query);
    }

    @Override
    public List<ReportDrawingCategoryAudit> listAuditByIds(List<Long> ids) {
        ReportDrawingCategoryAuditDTO query = new ReportDrawingCategoryAuditDTO();
        query.setIds(ids);
        return listReportDrawingCategoriesAudits(query);
    }

    @Override
    public List<ReportDrawingCategoryAudit> listReportDrawingCategoriesAudits(ReportDrawingCategoryAuditDTO query) {
        log.info("listReportDrawingCategoriesAudits - 查询报馆图纸分类审核列表, query={}", query);
        QueryWrapper<ReportDrawingCategoryAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(ReportDrawingCategoryAudit::getIsDeleted, BusinessConstant.DELETE_NO)
                .in(query.getIds() != null && !query.getIds().isEmpty(), ReportDrawingCategoryAudit::getId, query.getIds())
                .eq(query.getReportSpaceAuditId() != null, ReportDrawingCategoryAudit::getReportSpaceAuditId, query.getReportSpaceAuditId())
                .eq(query.getReportSpaceId() != null, ReportDrawingCategoryAudit::getReportSpaceId, query.getReportSpaceId())
                .eq(query.getDrawingCategoryId() != null, ReportDrawingCategoryAudit::getDrawingCategoryId, query.getDrawingCategoryId())
                .in(query.getDrawingCategoryIdList() != null && !query.getDrawingCategoryIdList().isEmpty(), ReportDrawingCategoryAudit::getDrawingCategoryId, query.getDrawingCategoryIdList())
                .orderByAsc(ReportDrawingCategoryAudit::getDrawingCategorySort)
        ;
        return list(queryWrapper);
    }

    @Override
    public ReportDrawingCategoryAudit getByReportSpaceIdAndDrawingId(Long reportSpaceId, Long drawingId) {
        ReportDrawingCategoryAuditDTO query = new ReportDrawingCategoryAuditDTO();
        query.setReportSpaceId(reportSpaceId);
        query.setDrawingCategoryId(drawingId);
        List<ReportDrawingCategoryAudit> list = listReportDrawingCategoriesAudits(query);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitBatch(List<ReportDrawingCategoryAuditDTO> list, Long reportSpaceAuditId) {
        log.info("submitBatch - 提交图纸分类审核列表, list={}, reportSpaceAuditId={}", list, reportSpaceAuditId);
        ReportDrawingCategoryAuditDTO reportDrawingCategoryAuditDTO = list.get(0);
        Long reportSpaceId = reportDrawingCategoryAuditDTO.getReportSpaceId();
        // 查询当前图纸分类列表
        List<ReportDrawingCategoryAudit> existAuditList = listByReportSpaceId(reportSpaceId);
        if (existAuditList == null || existAuditList.isEmpty()) {
            // 如果当前已有的图纸审核列表为为空，则是第一次提交，全部提交
            return saveBatch(list, reportSpaceAuditId);
        }
        // 重新提交审核未通过的图纸
        return resubmitBatch(list, existAuditList, reportSpaceAuditId, reportSpaceId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resubmitBatch(List<ReportDrawingCategoryAuditDTO> list, List<ReportDrawingCategoryAudit> existAuditList, Long reportSpaceAuditId, Long reportSpaceId) {
        // 如果之前已经提交过，则区分审核通过与其他状态
        // 当前准备提交的图纸分类map
        Map<Long, ReportDrawingCategoryAudit> reportDrawingCategoryAuditMap = new HashMap<>(16);
        existAuditList.forEach(audit -> reportDrawingCategoryAuditMap.put(audit.getDrawingCategoryId(), audit));
        List<ReportDrawingCategoryAuditDTO> needResubmitList = new ArrayList<>();
        for (ReportDrawingCategoryAuditDTO needSubmitAuditDTO: list) {
            ReportDrawingCategoryAudit existAudit = reportDrawingCategoryAuditMap.get(needSubmitAuditDTO.getDrawingCategoryId());
            // 如果当前提交的图纸分类，不在已审核列表中，则是新提交的数据，需要提交
            if (existAudit == null) {
                needResubmitList.add(needSubmitAuditDTO);
                continue;
            }
            reportDrawingCategoryAuditMap.remove(needSubmitAuditDTO.getDrawingCategoryId());
            // 主场审核通过，场馆还未审核，图纸审核状态为待审核，保留
            boolean isDrawingAuditSubmit = ReportDrawingCategoryAuditDrawingAuditStatusEnum.SUBMIT.eq(existAudit.getDrawingAuditStatus());
            // 主场与场馆都审核通过，图纸审核状态为已通过，保留
            boolean isDrawingAuditApproved = ReportDrawingCategoryAuditDrawingAuditStatusEnum.APPROVED.eq(existAudit.getDrawingAuditStatus());
            if (isDrawingAuditSubmit || isDrawingAuditApproved) {
                continue;
            }
            // 如果是审核未通过或待审核的图纸分类，则删除并发起审核
            needResubmitList.add(needSubmitAuditDTO);
        }
        // 已审核的记录不在此次提交中，需要删除
        List<Long> needDeleteDrawingCategoryIdList = new ArrayList<>(reportDrawingCategoryAuditMap.keySet());
        // 删除掉不需要的图纸分类审核记录
        removeBatchByReportSpaceIdAndDrawingCategoryId(reportSpaceId, needDeleteDrawingCategoryIdList);
        // 将当前审核未通过或待审核的图纸删除并重新提交
        return reSaveBatch(needResubmitList, reportSpaceAuditId, reportSpaceId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reSaveBatch(List<ReportDrawingCategoryAuditDTO> list, Long reportSpaceAuditId, Long reportSpaceId) {
        List<Long> needSubmitDrawingCategoryIdList = list
                .stream()
                .map(ReportDrawingCategoryAuditDTO::getDrawingCategoryId)
                .collect(Collectors.toList());
        removeBatchByReportSpaceIdAndDrawingCategoryId(reportSpaceId, needSubmitDrawingCategoryIdList);
        return saveBatch(list, reportSpaceAuditId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveReportDrawingCategoryAudit(ReportDrawingCategoryAuditDTO categoryDTO) {
        log.info("saveReportDrawingCategoryAudit - 保存报馆图纸分类审核, categoryDTO={}", categoryDTO);
        ReportDrawingCategoryAudit reportDrawingCategoryAudit = BeanUtil.toBean(categoryDTO, ReportDrawingCategoryAudit.class);
        save(reportDrawingCategoryAudit);
        // 批量保存图纸审核
        List<ReportDrawingAuditDTO> reportDrawingAuditList = categoryDTO.getReportDrawingAuditList();
        reportDrawingAuditList.forEach(reportDrawingAuditDTO -> {
            reportDrawingAuditDTO.setReportDrawingCategoryAuditId(reportDrawingCategoryAudit.getId());
            reportDrawingAuditDTO.setReportSpaceAuditId(reportDrawingCategoryAudit.getReportSpaceAuditId());
        });
        return reportDrawingAuditService.saveReportDrawingAuditBatch(reportDrawingAuditList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatch(List<ReportDrawingCategoryAuditDTO> list, Long reportSpaceAuditId) {
        log.info("saveBatch - 批量保存图纸分类审核, list={}, reportSpaceAuditId={}", list, reportSpaceAuditId);
        if (list == null || list.isEmpty()) {
            return false;
        }
        list.forEach(reportDrawingCategoryAuditDTO -> {
            reportDrawingCategoryAuditDTO.setReportSpaceAuditId(reportSpaceAuditId);
            saveReportDrawingCategoryAudit(reportDrawingCategoryAuditDTO);
        });
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBatchByReportSpaceAuditId(List<ReportDrawingCategoryAuditDTO> list, Long reportSpaceAuditId) {
        log.info("updateBatchByReportSpaceAuditId - 批量更新图纸分类审核列表, reportSpaceAuditId={}", reportSpaceAuditId);
        removeBatchByReportSpaceAuditId(reportSpaceAuditId);
        return saveBatch(list, reportSpaceAuditId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBatchAuditStatus(List<ReportDrawingCategoryAuditDTO> list) {
        log.info("updateBatchAuditStatus - 批量更新图纸分类审核状态, list={}", list);
        Map<Long, ReportDrawingCategoryAuditDTO> auditMap = new HashMap<>(16);
        list.forEach(reportDrawingCategoryAuditDTO -> auditMap.put(reportDrawingCategoryAuditDTO.getId(), reportDrawingCategoryAuditDTO));
        // 查询要更新的图纸类型列表
        List<Long> ids = new ArrayList<>(auditMap.keySet());
        List<ReportDrawingCategoryAudit> reportDrawingCategoryAuditList = listAuditByIds(ids);
        // 批量更新图纸类型列表
        reportDrawingCategoryAuditList.forEach(reportDrawingCategoryAudit -> {
            ReportDrawingCategoryAuditDTO auditDTO = auditMap.get(reportDrawingCategoryAudit.getId());
            reportDrawingCategoryAudit.setAuditStatus(auditDTO.getAuditStatus());
            reportDrawingCategoryAudit.setAuditOpinion(auditDTO.getAuditOpinion());
            reportDrawingCategoryAudit.setAuditTime(LocalDateTime.now());
            reportDrawingCategoryAudit.setAuditUserId(ContextUtil.getUserId());
            reportDrawingCategoryAudit.setAuditUserName(ContextUtil.getRealName());
            if (ReportDrawingCategoryAuditAuditStatusEnum.APPROVED.eq(reportDrawingCategoryAudit.getAuditStatus())) {
                // 如果场馆无需审核，主场审核通过，则该图纸类型审核通过，如果需要场馆审核，则不更新图纸审核状态，仍然为待审核
                if (ReportDrawingCategoryAuditVenueAuditStatusEnum.NOT_NEED_AUDIT.eq(reportDrawingCategoryAudit.getVenueAuditStatus())) {
                    reportDrawingCategoryAudit.setDrawingAuditStatus(ReportDrawingCategoryAuditDrawingAuditStatusEnum.APPROVED);
                }
            } else {
                // 主场审核未通过，则图纸总体未通过
                reportDrawingCategoryAudit.setDrawingAuditStatus(ReportDrawingCategoryAuditDrawingAuditStatusEnum.NOT_APPROVED);
            }
        });
        updateBatchById(reportDrawingCategoryAuditList);
        // 查询图纸列表
        List<ReportDrawingAudit> reportDrawingAuditList = reportDrawingAuditService.listByReportDrawingCategoryAuditIds(ids);
        // 批量保存图纸分类审核历史
        reportDrawingCategoryAuditHistoryService.saveBatchByReportDrawingCategoryAudit(reportDrawingCategoryAuditList, reportDrawingAuditList);
        // 批量保存主场搭建商图纸分类审核记录
        homeHomeBuilderDrawingCategoryAuditService.saveBatchByReportDrawingCategoryAuditList(reportDrawingCategoryAuditList, reportDrawingAuditList);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateVenueAuditStatus(ReportDrawingCategoryAuditDTO auditDTO) {
        log.info("updateBatchVenueAuditStatus - 更新图纸分类场馆审核状态, auditDTO={}", auditDTO);
        ReportDrawingCategoryAudit reportDrawingCategoryAudit = getByReportSpaceIdAndDrawingId(auditDTO.getReportSpaceId(), auditDTO.getDrawingCategoryId());
        if (reportDrawingCategoryAudit == null) {
            throw BizException.wrap(HomeExceptionCode.REPORT_VENUE_DRAWING_CATEGORY_NOT_EXIST.getCode(), "图纸分类不存在");
        }
        // 批量更新图纸分类场馆审核状态
        reportDrawingCategoryAudit.setVenueAuditStatus(auditDTO.getVenueAuditStatus());
        reportDrawingCategoryAudit.setVenueAuditOpinion(auditDTO.getVenueAuditOpinion());
        reportDrawingCategoryAudit.setVenueAuditTime(auditDTO.getVenueAuditTime());
        reportDrawingCategoryAudit.setVenueAuditUserId(auditDTO.getVenueAuditUserId());
        reportDrawingCategoryAudit.setVenueAuditUserName(auditDTO.getVenueAuditUserName());
        reportDrawingCategoryAudit.setDrawingAuditStatus(auditDTO.getDrawingAuditStatus());
        updateById(reportDrawingCategoryAudit);
        // 更新报馆审核的场馆审核状态
        return reportSpaceAuditService.updateVenueAuditStatusByReportSpaceId(reportDrawingCategoryAudit.getReportSpaceId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateReportSpaceAuditStatusWhenSubmit(Long reportSpaceId) {
        List<ReportDrawingCategoryAudit> reportDrawingCategoryAuditList = listByReportSpaceId(reportSpaceId);
        if (reportDrawingCategoryAuditList == null || reportDrawingCategoryAuditList.isEmpty()) {
            return false;
        }
        int submitCount = 0;
        int approvedCount = 0;
        for (ReportDrawingCategoryAudit reportDrawingCategoryAudit: reportDrawingCategoryAuditList) {
            if (ReportDrawingCategoryAuditAuditStatusEnum.APPROVED.eq(reportDrawingCategoryAudit.getAuditStatus())) {
                approvedCount++;
            }
            if (ReportDrawingCategoryAuditAuditStatusEnum.SUBMIT.eq(reportDrawingCategoryAudit.getAuditStatus())) {
                submitCount++;
            }
        }
        if (submitCount > 0) {
            return true;
        }
        // 如果当前审核的图纸已全部审核通过，则更新报馆图纸审核状态为通过
        if (approvedCount == reportDrawingCategoryAuditList.size()) {
            ReportSpaceAudit reportSpaceAudit = reportSpaceAuditService.getByReportSpaceId(reportSpaceId);
            reportSpaceAudit.setDrawingAuditStatus(ReportSpaceAuditDrawingAuditStatusEnum.APPROVED);
            reportSpaceAuditService.updateReportSpaceStatus(reportSpaceAudit);
            // todo 更新报馆记录的审核状态
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeBatchByReportSpaceAuditId(Long reportSpaceAuditId) {
        List<ReportDrawingCategoryAudit> list = listByReportSpaceAuditId(reportSpaceAuditId);
        removeByIdsOfLogic(list);
        return reportDrawingAuditService.removeBatchByReportSpaceAuditId(reportSpaceAuditId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeBatchByReportSpaceId(Long reportSpaceId) {
        List<ReportDrawingCategoryAudit> list = listByReportSpaceId(reportSpaceId);
        if (list == null || list.isEmpty()) {
            return false;
        }
        removeByIdsOfLogic(list);
        return reportDrawingAuditService.removeBatchByReportSpaceId(reportSpaceId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeBatchByReportSpaceIdAndDrawingCategoryId(Long reportSpaceId, List<Long> drawingCategoryIdList) {
        if (drawingCategoryIdList == null || drawingCategoryIdList.isEmpty()) {
            return false;
        }
        // 报馆ID，图纸类型ID列表查询图纸分类
        ReportDrawingCategoryAuditDTO query = new ReportDrawingCategoryAuditDTO();
        query.setReportSpaceId(reportSpaceId);
        query.setDrawingCategoryIdList(drawingCategoryIdList);
        List<ReportDrawingCategoryAudit> list = listReportDrawingCategoriesAudits(query);
        if (list == null || list.isEmpty()) {
            return false;
        }
        // 删除图纸分类
        removeByIdsOfLogic(list);
        // 删除图纸
        return reportDrawingAuditService.removeBatchByReportSpaceIdAndDrawingCategoryId(reportSpaceId, drawingCategoryIdList);
    }

}
